﻿using System;
using System.Configuration;
using System.Text.RegularExpressions;
using System.IO;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Shuba.Model;
using Shuba.Business;
using System.DirectoryServices;
using System.Web.Security;


namespace Shuba.Web
{//
    public class basePage : System.Web.UI.Page
    {
        public static bool ByPassAD()
        {
            return true;
        }

        public void RestartPage()
        {
            Response.Redirect(Request.Url.PathAndQuery);
        }

        public string GetPageTitle(string UniqueName)
        {
            string AppCode = ConfigurationManager.AppSettings["app.code"];

            Shuba.Business.Menu _Menu = new Shuba.Business.Menu();
            Shuba.Model.MenuInfo _MenuInfo = _Menu.Get(UniqueName, AppCode);
            return _MenuInfo.Name;
        }

        public string GetUserAccess(string uniqueName)
        {
            string status = "";
            string AppCode = ConfigurationManager.AppSettings["app.code"];

            FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
            FormsAuthenticationTicket ticket = id.Ticket;
            string Userdata = ticket.UserData;
            string[] ArrUserData = Userdata.Split('~');

            Shuba.Business.Authorization acl = new Authorization();
            Shuba.Business.Menu _Menu = new Shuba.Business.Menu();
            Shuba.Model.MenuInfo _MenuInfo = _Menu.Get(uniqueName, AppCode);
            Shuba.Business.User user = new User();

            Shuba.Model.UserInfo info = user.Get(HttpContext.Current.User.Identity.Name, AppCode);

            status = acl.GetUserPrivilege(info.Id, _MenuInfo.Id, AppCode);

            return status;
        }

        public bool IsUserView(string usrAcl)
        {
            bool IsViewUser = false;
            if (usrAcl != null)
            {
                if (usrAcl.Substring(0, 1) == "1") IsViewUser = true;
                else IsViewUser = false;
            }
            else IsViewUser = false;
            return IsViewUser;
        }

        public bool IsUserAdd(string usrAcl)
        {
            bool IsAddUser = false;
            if (usrAcl != null)
            {
                if (usrAcl.Substring(1, 1) == "1") IsAddUser = true;
                else IsAddUser = false;
            }
            else IsAddUser = false;
            return IsAddUser;
        }

        public bool IsUserEdit(string usrAcl)
        {
            bool IsEditUser = false;
            if (usrAcl != null)
            {
                if (usrAcl.Substring(2, 1) == "1") IsEditUser = true;
                else IsEditUser = false;
            }
            else IsEditUser = false;
            return IsEditUser;
        }

        public bool IsUserDelete(string usrAcl)
        {
            bool IsDeleteUser = false;
            if (usrAcl != null)
            {
                if (usrAcl.Substring(3, 1) == "1") IsDeleteUser = true;
                else IsDeleteUser = false;
            }
            else IsDeleteUser = false;
            return IsDeleteUser;
        }

        public bool IsUserChecker(string usrAcl)
        {
            bool IsCheckerUser = false;
            if (usrAcl != null)
            {
                if (usrAcl.Substring(4, 1) == "1") IsCheckerUser = true;
                else IsCheckerUser = false;
            }
            else IsCheckerUser = false;
            return IsCheckerUser;
        }

        public bool IsValidEntryFormat(string usrEntry, string DataType)
        {
            bool IsValid = false;

            string UserEntry = usrEntry.Trim();
            string FormatType = DataType.Trim().ToUpper();

            if (UserEntry == "") return true;

            switch (FormatType)
            {
                case "NS": //Number and Space
                    IsValid = Regex.IsMatch(UserEntry, "^[\\d\\s]+$"); //"^[0-9\\s]+$
                    break;
                case "N": //Number Only
                    IsValid = Regex.IsMatch(UserEntry, "^\\d+$"); //[0-9]+$
                    break;
                case "M": //Money
                    IsValid = Regex.IsMatch(UserEntry, "^[\\d.,]+$"); //[0-9]+$
                    break;
                case "C": //Characters Only
                    IsValid = Regex.IsMatch(UserEntry, "^[0-9a-zA-Z\\s]+$"); //[0-9]+$
                    break;
                case "D": //Date Format MM-DD-YYYY
                    //IsValid = Regex.IsMatch(UserEntry, "^([1-9]|0[1-9]|1[012])[- /.]([1-9]|0[1-9]|[12][0-9]|3[01])[- /.][0-9]{4}$");
                    DateTime dt;
                    IsValid = DateTime.TryParse(UserEntry, out dt);
                    break;
            }
            return IsValid;
        }

        public void AlertAndRedirect(string message, string url)
        {
            /*
            string script = "<script language=javascript>alert('" + message.Replace("'", "\'") + "');navigate('" + url + "');</script>";
            if (!Page.ClientScript.IsStartupScriptRegistered("AlertAndRedirect"))
            {
                Page.ClientScript.RegisterStartupScript(this.GetType(), "AlertAndRedirect", script);
            }
            Response.Write(script);
            */

            string script = "alert('" + message.Replace("'", "\'") + "');navigate('" + url + "');";
            if (!Page.ClientScript.IsStartupScriptRegistered("Alert"))
            {
                ScriptManager.RegisterStartupScript(Page, this.GetType(), "Alert", script, true);
            }
        }

        public void Alert(string message)
        {
            /*
            string script = "<script language=javascript>alert('" + message.Replace("'", "\'") + "');</script>";
            if (!Page.ClientScript.IsStartupScriptRegistered("Alert"))
            {
                Page.ClientScript.RegisterStartupScript(this.GetType(), "Alert", script, true);
            }
            Response.Write(script);
            */
            string script = "alert('" + message.Replace("'", "\'") + "');";
            if (!Page.ClientScript.IsStartupScriptRegistered("Alert"))
            {
                ScriptManager.RegisterStartupScript(Page, this.GetType(), "Alert", script, true);
            }
        }

        public void AlertConfirmation(string message, string url)
        {
            string script = "var answer = confirm(\"" + message + "\");";
            script += "if (answer) { window.location = \"" + url + "\"; } else { location.href ='default.aspx'; }";

            if (!Page.ClientScript.IsStartupScriptRegistered("AlertConfirmation"))
            {
                ScriptManager.RegisterStartupScript(Page, this.GetType(), "AlertConfirmation", script, true);
            }
        }

        public void CallJs(string NameJs)
        {
            string ScriptJs = NameJs + "();";
            if (!Page.ClientScript.IsStartupScriptRegistered(NameJs))
            {
                ScriptManager.RegisterStartupScript(Page, this.GetType(), NameJs, ScriptJs, true);
            }
        }

        public void AddLog(string type, string description)
        {
            string Desc = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(description.ToLower());
            TransactionLog log = new TransactionLog();
            log.Add(new TransactionLogInfo(ProcessingDate(), HttpContext.Current.User.Identity.Name, type.ToUpper(), Desc));
        }

        public void InitSort()
        {
            ViewState.Add("Sort", "DESC");
            ViewState.Add("SortEx", "");
        }

        public void SortDirection(string column, string direction)
        {
            if (ViewState["SortEx"].ToString() == column)
            {
                if (ViewState["Sort"].ToString() == "ASC")
                {
                    ViewState["Sort"] = "DESC";
                }
                else
                {
                    ViewState["Sort"] = "ASC";
                }
            }
            else
            {
                ViewState["Sort"] = "ASC";
            }
        }

        public long CheckExpired(string LDAPUser, string LDAPPass)
        {
            long daysLeft = 0;
            try
            {
                long lastChanged = 0, maxDays = 0, maxPwdAge = 0;
                string LDAPServer = ConfigurationManager.AppSettings["ldap"];

                DirectoryEntry root = new DirectoryEntry(LDAPServer, LDAPUser, LDAPPass, AuthenticationTypes.Secure);
                DirectorySearcher searcher = new DirectorySearcher(root);

                searcher.Filter = "(&(objectClass=person)(SAMAccountName=" + LDAPUser + "))";
                searcher.PropertiesToLoad.Add("pwdlastset");

                SearchResult results = searcher.FindOne();

                if (results.Properties["pwdlastset"].Count > 0) lastChanged = (long)results.Properties["pwdlastset"][0];

                searcher = new DirectorySearcher(root);
                searcher.Filter = "maxPwdAge=*";
                searcher.PropertiesToLoad.Add("maxPwdAge");
                results = searcher.FindOne();

                if (results.Properties["maxPwdAge"].Count > 0) maxPwdAge = (Int64)results.Properties["maxPwdAge"][0];
                maxDays = maxPwdAge / -864000000000;

                daysLeft = maxDays - DateTime.Today.Subtract(Convert.ToDateTime(DateTime.FromFileTime((long)lastChanged).ToShortDateString())).Days;
            }
            catch (Exception) { }
            return daysLeft;
        }

        public bool CheckLDAPUser(string LDAPUser, string LDAPPass)
        {
            //FOR TESTING PURPOSES PLEASE CHANGE return value into true
            if (ByPassAD())
                return true;

            string LDAPServer = ConfigurationManager.AppSettings["ldap"];

            DirectoryEntry entry = new DirectoryEntry(LDAPServer, LDAPUser, LDAPPass);
            try
            {
                string EName = entry.Name; //Untuk Trap Error (LDAP tidak dapat) atau berhasil

                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public string CheckLDAPUser(string LDAPServer, string LDAPUser, string LDAPPass, string LDAPSearchUser)
        {
            string UserName = "";

            if (ByPassAD())
                return UserName = "User Name";//FOR TESTING PURPOSE

            //DirectoryEntry entry = new DirectoryEntry(LDAPServer, LDAPUser, LDAPPass, AuthenticationTypes.Secure);
            DirectoryEntry entry = new DirectoryEntry(LDAPServer, LDAPUser, LDAPPass);
            DirectorySearcher mySearcher = new DirectorySearcher(entry);

            try
            {
                mySearcher.Filter = "(&(ObjectClass=user)(SAMAccountName=" + LDAPSearchUser + "))";   //using network login name
                //mySearcher.Filter = "(userPrincipalName=" + userIDEmail + ")";  // using email address

                mySearcher.PropertiesToLoad.Add("cn"); // network login name
                mySearcher.PropertiesToLoad.Add("userPrincipalName");//email
                //mySearcher.PropertiesToLoad.Add("givenName");//first name
                mySearcher.PropertiesToLoad.Add("displayName");//Display name
                //mySearcher.PropertiesToLoad.Add("initials");//middle initial
                //mySearcher.PropertiesToLoad.Add("sn");//last name

                SearchResult searchResult = mySearcher.FindOne();

                if (searchResult != null)
                {
                    string UNetworkLoginName = (string)searchResult.Properties["cn"][0];
                    string UEmail = (string)searchResult.Properties["userPrincipalName"][0];
                    //string UFName = (string)searchResult.Properties["givenName"][0];
                    string UDisplayName = (string)searchResult.Properties["displayName"][0];

                    UserName = UDisplayName;
                }
            }
            catch
            {
                UserName = "";
            }
            return UserName;
        }

        public static DateTime ProcessDate = DateTime.Now;

        public static DateTime ProcessingDate()
        {
            return new DateTime(
                ProcessDate.Year,
                ProcessDate.Month,
                ProcessDate.Day,
                DateTime.Now.Hour,
                DateTime.Now.Minute,
                DateTime.Now.Second,
                DateTime.Now.Millisecond,
                ProcessDate.Kind);
        }
    }

    public class GridViewExportUtil
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="gv"></param>
        public static void Export(string fileName, GridView gv)
        {
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.AddHeader(
                "content-disposition", string.Format("attachment; filename={0}", fileName));
            HttpContext.Current.Response.ContentType = "application/ms-excel";

            using (StringWriter sw = new StringWriter())
            {
                using (HtmlTextWriter htw = new HtmlTextWriter(sw))
                {
                    //  Create a table to contain the grid
                    Table table = new Table();

                    //  include the gridline settings
                    table.GridLines = gv.GridLines;

                    //  add the header row to the table
                    if (gv.HeaderRow != null)
                    {
                        GridViewExportUtil.PrepareControlForExport(gv.HeaderRow);
                        table.Rows.Add(gv.HeaderRow);
                    }

                    //  add each of the data rows to the table
                    foreach (GridViewRow row in gv.Rows)
                    {
                        GridViewExportUtil.PrepareControlForExport(row);
                        table.Rows.Add(row);
                    }

                    //  add the footer row to the table
                    if (gv.FooterRow != null)
                    {
                        GridViewExportUtil.PrepareControlForExport(gv.FooterRow);
                        table.Rows.Add(gv.FooterRow);
                    }

                    //  render the table into the htmlwriter
                    table.RenderControl(htw);

                    //  render the htmlwriter into the response
                    HttpContext.Current.Response.Write(sw.ToString());
                    HttpContext.Current.Response.End();
                }
            }
        }

        /// <summary>
        /// Replace any of the contained controls with literals
        /// </summary>
        /// <param name="control"></param>
        private static void PrepareControlForExport(Control control)
        {
            for (int i = 0; i < control.Controls.Count; i++)
            {
                Control current = control.Controls[i];
                if (current is LinkButton)
                {
                    control.Controls.Remove(current);
                    control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text));
                }
                else if (current is ImageButton)
                {
                    control.Controls.Remove(current);
                    control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText));
                }
                else if (current is HyperLink)
                {
                    control.Controls.Remove(current);
                    control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text));
                }
                else if (current is DropDownList)
                {
                    control.Controls.Remove(current);
                    control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text));
                }
                else if (current is CheckBox)
                {
                    control.Controls.Remove(current);
                    control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False"));
                }

                if (current.HasControls())
                {
                    GridViewExportUtil.PrepareControlForExport(current);
                }
            }
        }
    }
}